from sklearn.datasets import load_breast_cancer
import pandas as pd
from sklearn.ensemble import AdaBoostClassifier
from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import train_test_split
import numpy as np
class Adabssetclassifier():
    def __init__(self,n_estimators,Lr=1):
        self.n_estimators = n_estimators
        self.models = []
        self.weights = []
        self.a_params = []
        self.Lr = Lr
    def fit(self,X,y):
        W = (np.ones(len(X)))/len(X)
        for i in range(self.n_estimators):
            model = DecisionTreeClassifier(max_depth=2)
            model.fit(X,y,sample_weight=W)
            result = model.predict(X)
            e = np.dot(W.T,result!=y)
            #print(e)
            epsilon = 0.0001
            a = 0.5*np.log((1-e)/(e+epsilon))
            Z = np.dot(W.T,np.exp(-a*self.Lr*y*result))
            W = W/Z * np.exp(-a*self.Lr*y*result)
            self.models.append(model)
            self.weights.append(W)
            self.a_params.append(a)

    def predict(self,X):
        F = sum(self.a_params[i]*self.Lr*self.models[i].predict(X) for i in range(self.n_estimators))
        G = np.sign(F)
        return G
    def score(self,y,H):
        acc_score = sum(np.where(H==y,1,0))/len(y)
        return acc_score

if __name__ == '__main__':
    breast_cancer = load_breast_cancer()
    X ,y = breast_cancer.data,breast_cancer.target
    x_train,x_test,y_train,y_test = train_test_split(X,y,test_size=0.3,random_state=1)

    print("==========================手写===========================")
    Ada = Adabssetclassifier(n_estimators=6)
    Ada.fit(x_train,y_train)
    print("测试集预测值：\n",Ada.predict(x_test))
    print("测试集精度",Ada.score(y_test,Ada.predict(x_test)))

    print("==========================调库===========================")
    Ada = AdaBoostClassifier(n_estimators=6)
    Ada.fit(x_train,y_train)
    print("测试集预测值：\n", Ada.predict(x_test))
    from sklearn.metrics import accuracy_score
    print("测试集精度", accuracy_score(y_test, Ada.predict(x_test)))